package com.eece411.project.p2;

import java.util.ArrayList;

public class Cluster implements Instance{
	private ArrayList<Instance> members=new ArrayList<Instance>(3);
	private int latency;
	public Cluster(Instance i1,Instance i2,Instance i3){
		// Sort the node by latency
		if(i1.getLatency()<=i2.getLatency()){
			if(i1.getLatency()<=i3.getLatency()){
				members.add(i1);
				members.add(i2);
				members.add(i3);
				System.out.println("123");
			} else {
				members.add(i3);
				members.add(i1);
				members.add(i2);
				System.out.println("312");
			}
		} else if (i1.getLatency()<=i3.getLatency()) {
			if(i2.getLatency()<=i3.getLatency()){
				members.add(i2);
				members.add(i1);
				members.add(i3);
				System.out.println("213");
				
			} else {
				members.add(i1);
				members.add(i3);
				members.add(i2);
				System.out.println("132");
			}
		} else {
			if(i2.getLatency()<=i3.getLatency()){
				members.add(i2);
				members.add(i3);
				members.add(i1);
				System.out.println("231");
			} else {
				members.add(i3);
				members.add(i2);
				members.add(i1);
				System.out.println("321");
			}
		}
		int tLatency=0;
		for(Instance i : members){
			tLatency+=i.getLatency();
		}
		this.latency=tLatency/3;
	}
	@Override
	public boolean put(byte[] key, byte[] data, boolean isReplication) {
		if (members.get(0).getLatency()==-1 && !isReplication){
			// If local storage and is the first responsable node triger replication
			ES.getInstance().execute(new SyncThread(members.get(1),key,data));
			ES.getInstance().execute(new SyncThread(members.get(2),key,data));
		}
		// Loop on each Instance to do a put break at the first to reply
		boolean result = false;
		for(Instance i : members){
			try {
				result = i.put(key, data,isReplication);
				break;
			} catch (deadException e) {
				System.out.println("--- Node not responding");
			}
		}
		return result;
	}
	@Override
	public byte[] get(byte[] key) {
		// Loop on each Instance to do a put break at the first to reply
		byte[] data = null;
		for(Instance i : members){
			try {
				data = i.get(key);
				break;
			} catch (deadException e) {
				System.out.println("--- Node not responding");
			}
		}
		return data;
	}
	@Override
	public boolean remove(byte[] key, boolean isReplication) {
		if (members.get(0).getLatency()==-1 && !isReplication){
			// If local storage and is the first responsable node triger replication
			ES.getInstance().execute(new SyncThread(members.get(1),key));
			ES.getInstance().execute(new SyncThread(members.get(2),key));
		}
		boolean result = false;
		// Loop on each Instance to do a put break at the first to reply
		for(Instance i : members){
			try {
				result = i.remove(key,isReplication);
				break;
			} catch (deadException e) {
				System.out.println("--- Node not responding");
			}
		}
		return result;
	}
	@Override
	public boolean containsKey(byte[] key) {
		boolean result = false;
		// Loop on each Instance to do a put break at the first to reply
		for(Instance i : members){
			try {
				result = i.containsKey(key);
				break;
			} catch (deadException e) {
				System.out.println("--- Node not responding");
			}
		}
		return result;
	}

	@Override
	public int getLatency() {
		return this.latency;
	}
	@Override
	public int compareTo(Instance instance) {
		return instance.getLatency()-this.getLatency();
	}
	@Override
	public boolean equals(String s) {
		return false;
	}
}
